// *************************************************************************************************
//
//	Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ 
//	 
//	 
//	  Redistribution and use in source and binary forms, with or without 
//	  modification, are permitted provided that the following conditions 
//	  are met:
//	
//	    Redistributions of source code must retain the above copyright 
//	    notice, this list of conditions and the following disclaimer.
//	 
//	    Redistributions in binary form must reproduce the above copyright
//	    notice, this list of conditions and the following disclaimer in the 
//	    documentation and/or other materials provided with the   
//	    distribution.
//	 
//	    Neither the name of Texas Instruments Incorporated nor the names of
//	    its contributors may be used to endorse or promote products derived
//	    from this software without specific prior written permission.
//	
//	  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
//	  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
//	  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
//	  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
//	  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
//	  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
//	  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
//	  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
//	  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
//	  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
//	  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// *************************************************************************************************
// Radio core access functions. Taken from TI reference code for CC430.
// *************************************************************************************************

// system
#include "project.h"

// driver
#include "rf1a.h"
#include "timer.h"

// logic
#include "rfsimpliciti.h"
#include "bluerobin.h"


// *************************************************************************************************
// Extern section

// SimpliciTI CC430 radio ISR - located in SimpliciTi library
extern void MRFI_RadioIsr(void);

// BlueRobin CC430 radio ISR - located in BlueRobin library
extern void BlueRobin_RadioISR_v(void);


// *************************************************************************************************
// @fn          radio_reset
// @brief       Reset radio core. 
// @param       none
// @return      none
// *************************************************************************************************
void radio_reset(void)
{
	volatile u16 i;
	u8 x;
	
	// Reset radio core
	Strobe(RF_SRES);
	// Wait before checking IDLE 
	for (i=0; i<100; i++);
	do {
		x = Strobe(RF_SIDLE);
	} while ((x&0x70)!=0x00);  
	
	// Clear radio error register
	RF1AIFERR = 0;
}


// *************************************************************************************************
// @fn          radio_powerdown
// @brief       Put radio to SLEEP mode. 
// @param       none
// @return      none
// *************************************************************************************************
void radio_powerdown(void)
{
  /* Chip bug: Radio does not come out of this SLEEP when put to sleep
   * using the SPWD cmd. However, it does wakes up if SXOFF was used to
   * put it to sleep.
   */
	// Powerdown radio
	Strobe(RF_SIDLE);
	Strobe(RF_SPWD);	
}



// *************************************************************************************************
// @fn          radio_sxoff
// @brief       Put radio to SLEEP mode (XTAL off only). 
// @param       none
// @return      none
// *************************************************************************************************
void radio_sxoff(void)
{
  /* Chip bug: Radio does not come out of this SLEEP when put to sleep
   * using the SPWD cmd. However, it does wakes up if SXOFF was used to
   * put it to sleep.
   */
	// Powerdown radio
	Strobe(RF_SIDLE);
	Strobe(RF_SXOFF);	
}


// *************************************************************************************************
// @fn          open_radio
// @brief       Prepare radio for RF communication. 
// @param       none
// @return      none
// *************************************************************************************************
void open_radio(void)
{
	// Reset radio core
	radio_reset();

	// Enable radio IRQ
	RF1AIFG &= ~BIT4;                         // Clear a pending interrupt
  	RF1AIE  |= BIT4;                          // Enable the interrupt  	
}




// *************************************************************************************************
// @fn          close_radio
// @brief       Shutdown radio for RF communication. 
// @param       none
// @return      none
// *************************************************************************************************
void close_radio(void)
{
	// Disable radio IRQ
	RF1AIFG = 0;
	RF1AIE  = 0; 
		
	// Reset radio core
	radio_reset();
	
	// Put radio to sleep
	radio_powerdown();
}


// *************************************************************************************************
// @fn          GDOx_ISR
// @brief       GDO0/2 ISR to detect received packet. 
//				In BlueRobin mode:  capture packet end time and decode received packet
//				In SimpliciTI mode: go to SimpliciTI handler
// @param       none
// @return      none
// *************************************************************************************************
#pragma vector=CC1101_VECTOR
__interrupt void radio_ISR(void)
{
	u8 rf1aivec = RF1AIV;
	
	// Forward to SimpliciTI interrupt service routine
	if (is_rf())
	{
		MRFI_RadioIsr();
	}
	else // BlueRobin packet end interrupt service routine
	{		
		if (rf1aivec == RF1AIV_RFIFG9)
		{    
			if ((sBlueRobin.state == BLUEROBIN_SEARCHING) || (sBlueRobin.state == BLUEROBIN_CONNECTED))
			{
				BlueRobin_RadioISR_v();
			}
		}
		else if (rf1aivec == RF1AIV_NONE) // RF1A interface interrupt (error etc.)
		{
			asm("	nop"); // break here
		}
	}
}
